#ifndef THEATER_C
#define THEATER_C

int THEATER_TESTS = -9999;




int seats[5][5];


int custsSeated=0;


int customerTheater = 0;
int takingTickets = 1;
int ticketsTaken;
int seatedPeople=0;
int lobbyLock;
int lobbyCV;
int customersServed;
int ticketClerks;
int foodClerks;
int ticketTakers;
int customers;

int movieStarted=0;


int takingTicketsLock;



struct CustData{
	int groupSize;
};



int numberOfCustomers;
int seatsFreeLock;
int seatsFree[5];

int initialLock;

int BREAK_LENGTH;

int MAX_TAKER;

int theaterLock;
int theaterCV;


#include "syscall.h"
#include "ClerkState.h"
#include "ticketclerk.c"
#include "foodclerk.c"
#include "tech.c"
#include "manager.c"
#include "tickettaker.c"
#include "customer.c"

int
main()
{
	SetupTheater();	
}

void SetupTheater()
{
		char c;
		int i,j;
		int numberOfClerks;
		int custPerGroup;
		int extraCust;
		int dumbCounterThing;
		/*initialLock = LockCreate("Initial Lock", 12);*/
		lobbyLock = LockCreate("Lobby Lock", 10);
		lobbyCV = CVCreate("The Lobby Is A Boring Place", 27);
		theaterLock = LockCreate("Theater Lock", 12);
		theaterCV = CVCreate("Theater CV", 10);
		numberOfFoodClerksLock = LockCreate("Number Of Food Clerks",21);
		numberOfTicketClerksLock = LockCreate("Number Of Ticket Clerks Lock",28);
		TakerNumberLock = LockCreate("Number Of Ticket Takers",23);
		customersInGroupLock = LockCreate("Customers in group lock",23);
		numberOfCustomersCV = CVCreate("Number of customers CV",22);
		numberOfCustomersLock = LockCreate("Number of Customers Lock",24);
		numberOfCustomers=0;
		BREAK_LENGTH=200;
		MAX_TAKER = 3;
		/*LockAcquire(initialLock);*/
		while(1)
		{
			char choice;
			Write("Would you like to make your own theater? y/n \n",47,1);
			choice=getChar();
			if(choice=='y')
			{
				customerTheater = 1;
				break;	
			}
			else if(choice=='n')
				break;
		}
		
		while(c = getChar() != '\n' && c != '\0');


		for(i = 0; i<5; i++)
		{
			for(j = 0; j<5; j++)
			{
				seats[i][j]=1;
			}

			seatsFree[i] = 5;
		}
		
		seatsFreeLock = LockCreate("seats free line lock", 20);
		ticketClerkLineLock = LockCreate("ticket clerk line lock", 22);

		if(customerTheater)
		{
			while(1)
			{
				Write("How Many Ticket Clerks?\n",25,1);
				numberOfClerks = Scan();
				/*Write("numberOfClerks is %i\n", numberOfClerks);*/
				if(numberOfClerks<6&&numberOfClerks>0)
				{
					break;
				}
			}
		}
		else
			numberOfClerks =5;/*(rand()%MAX_CLERK)+1;*/
		ticketClerks=numberOfClerks;
		for(i = numberOfClerks; i < 5; i++)
		{

			ticketClerkConditionVariables[i] = -1;
			ticketClerkLineConditionVariables[i] = -1;
			ticketClerkLocks[i] =-1;
			ticketClerkLineCount[i] = 999999;
			ticketEarnings[i]=-1;
			ticketClerkState[i] = no_clerk;
		}

		for(i = numberOfClerks-1; i >= 0; i--)
		{

			ticketClerkConditionVariables[i] = CVCreate("ticketClerkCondition", 20);
			ticketClerkLineConditionVariables[i] = CVCreate("ticketClerkLineCondition", 24);
			ticketClerkLocks[i] = LockCreate("Ticket Clerk Lock", 17);
			ticketClerkLineCount[i] = 0;
			ticketEarnings[i]=0;
			ticketClerkState[i] = available;
			
		}
		
	
		foodClerkLineLock = LockCreate("Food Clerk Line Lock", 20);
		if(customerTheater)
		{
			while(1)
			{
				Write("How Many Food Clerks?\n",23,1);
				numberOfClerks = Scan();
				/*printf("numberOfClerks is %i\n", numberOfClerks);*/
				if(numberOfClerks<6&&numberOfClerks>0)
				{
					break;
				}
			}
		}
		else
			numberOfClerks = 1;
		foodClerks=numberOfClerks;
		for(i = numberOfClerks; i<5; i++)
		{

			foodClerkConditionVariables[i] = -1;
			foodClerkLineConditionVariables[i] = -1;
			foodClerkLocks[i] = -1;
			foodClerkLineCount[i] = 9999;
			foodEarnings[i] = -1;
			foodClerkStates[i] = no_clerk;
		}
		
		for(i = numberOfClerks-1; i >= 0; i--)
		{

			foodClerkConditionVariables[i] = CVCreate("Food Clerk Condition", 20);
			foodClerkLineConditionVariables[i] = CVCreate("Food Clerk Line Condition", 25);
			foodClerkLocks[i] = LockCreate("Food Clerk Lock", 15);
			foodClerkLineCount[i] = 0;
			foodEarnings[i] = 0;
			foodClerkStates[i] = available;
			
		}
		
		ticketTakerLineLock = LockCreate("Ticket Taker Line Lock", 22);
		takingTickets = 1;
		ticketsTaken = 0;
		totalTicketLock = LockCreate("Total Ticket Lock", 17);
		takingTicketsLock = LockCreate("Taking Tickets Lock", 19);
		if(customerTheater)
		{
			while(1)
			{
				Write("How Many Ticket Takers?\n",25,1);
				numberOfClerks = Scan();
				/*printf("numberOfClerks is %i\n", numberOfClerks);*/
				if(numberOfClerks<4&&numberOfClerks>0)
				{
					break;
				}
			}
		}
		else
			numberOfClerks = 3;
		ticketTakers = numberOfClerks;
		for(i = numberOfClerks; i<5; i++)
		{

			ticketTakerConditionVariables[i] = -1;
			ticketTakerLineConditionVariables[i] = -1;
			ticketTakerLocks[i] = -1;
			ticketTakerLineCount[i] = 9999;
			ticketTakerStates[i] = no_clerk;
		}
		
		for(i = numberOfClerks-1; i >= 0; i--)
		{
			ticketTakerConditionVariables[i] = CVCreate("Ticket Taker Condition", 22);
			ticketTakerLineConditionVariables[i] = CVCreate("Ticket Taker Line Condition", 27);
			ticketTakerLocks[i] = LockCreate("Ticket Taker Lock", 17);
			ticketTakerLineCount[i] = 0;
			ticketTakerStates[i] = available;
			
			
		}
			
		techMovieVariable = CVCreate("Tech Movie Condition Variable", 29);
		techManagerVariable = CVCreate("Tech Manager Condition Variable", 31);
		techLock = LockCreate("Tech Lock", 9);


		managerLock = LockCreate("Manager Lock", 12);
		takingTicketsLock = LockCreate("Taking Tickets Lock", 19);
		startMovieConditionVariable = CVCreate("Start Movie Condition Variable", 30);
		managerClerkGoingOnBreakConditionVariable = CVCreate( "manager clerk going on break cv", 31);
	
		for(i =0;i<ticketClerks;i++)
		{
			Fork(TicketClerk);
		}
		for(i =0;i<foodClerks;i++)
		{
			Fork(FoodClerk);
		}
		for(i =0;i<ticketTakers;i++)
		{
			Fork(TicketTaker);
		}
		Fork(Tech);
	
		for(i=0;i<MAX_CUSTOMER;i++)
		{
			customersInGroup[i]=0;
		}

		customers = 0;
		if(customerTheater == 0) {
			groupTotal = 3;
			for(i = 0; i<groupTotal;i++)
			{
				custDataArray[i].groupSize = rand()%5 + 1;
				customers += custDataArray[i].groupSize;
				customerConditionVariable[i] = CVCreate("customer CV", 11);
				customerLock[i] = LockCreate("customer lock", 13);
				headCustomerCondition[i]=CVCreate("Head Customer Condition", 23);
				popAmount[i]=0;
				sodaAmount[i]=0;
				foodReportCount[i] = 0;
				Write1("Group Size is %i ",17,1,custDataArray[i].groupSize);
				Write1("for cust %i\n",13,1,i);
				for(j=0;j<custDataArray[i].groupSize-1;j++)
				{
					
					Fork(MiniCustomer);
				}
				
				LockAcquire(numberOfCustomersLock);
				Write1("%i and ",6,1,custDataArray[i].groupSize-1);
				Write1("%i \n",5,1,customersInGroup[i]);
				if(custDataArray[i].groupSize>1&&custDataArray[i].groupSize-1>customersInGroup[i])
				{
					Wait(numberOfCustomersCV,numberOfCustomersLock);
					Write1("%i and ",6,1,custDataArray[i].groupSize-1);
					Write1("%i \n",5,1,customersInGroup[i]);
					Write("Mini custs are made\n",21,1);
				}
				else
				{
					LockRelease(numberOfCustomersLock);
				}

				Fork(CustomerAgent);
			}
	
		} else {

			/*ask the user for # of customer groups and # of customers*/
			while(1) {
				Write("How many customers would you like to make?\n",44,1);
				customers = Scan();
	
				Write("How many groups would you like to make?\n",41,1);
				groupTotal = Scan();
				
				/*check if data is bad*/
				if(customers < groupTotal) {
					Write("Too few customers for that many groups. Try again.\n",52,1);
				}
				else if(customers > groupTotal*5) {
					Write("Too many customers for that many groups. Try again.\n",53,1);
				}
				else if(customers <= 0) {
					Write("Customers must be positive.\n",29,1);
				}
				else if(groupTotal <= 0) {
					Write("Groups must be positive.\n",26,1);
				}
				else if(groupTotal > 100) {
					Write("Cannot have more than 100 groups.\n",35,1);
				}
				else {
					/*data was fine so contine*/
					break;
				}
			}
	
			custPerGroup = customers / groupTotal;
			extraCust = customers % groupTotal;
			dumbCounterThing = 0;
	
			/*calculating customers in each group*/
			
			for(i = 0; i < groupTotal; i++) {
				popAmount[i]=0;
				sodaAmount[i]=0;
				foodReportCount[i] = 0;

				if(dumbCounterThing < extraCust) {
					custDataArray[i].groupSize = custPerGroup + 1;
					customers += custDataArray[i].groupSize;
					customerConditionVariable[i] = CVCreate("customer CV", 11);
					customerLock[i] = LockCreate("customer lock", 13);
					headCustomerCondition[i]=CVCreate("Head Customer Condition", 23);
					for(j=0;j<custDataArray[i].groupSize-1;j++)
					{
						Fork(MiniCustomer);
					}
					
		
					dumbCounterThing++;
				} else {
					custDataArray[i].groupSize = custPerGroup;
					customers += custDataArray[i].groupSize;
					customerConditionVariable[i] = CVCreate("customer CV", 11);
					customerLock[i] = LockCreate("customer lock", 13);
					headCustomerCondition[i]=CVCreate("Head Customer Condition", 23);
					for(j=0;j<custDataArray[i].groupSize-1;j++)
					{
						Fork(MiniCustomer);
					}
				}
				
				LockAcquire(numberOfCustomersLock);
				if(custDataArray[i].groupSize-1<customersInGroup[i])
				{
					Wait(numberOfCustomersCV,numberOfCustomersLock);
				}
				else
				{
					LockRelease(numberOfCustomersLock);
				}
			}
		
			for(i = 0; i<groupTotal;i++)
			{

				Fork(CustomerAgent);
			}
			
		}
		
		Fork(Manager);

		Exit(0);
}
#endif
